﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Xml;
using System.Xml.XPath;

namespace DotNet.Utilities
{
    /// <summary>
    /// 包含对XML操作的函数集合
    /// </summary>
    public class XmlUtil
    {
        /// <summary>
        /// 返回XML的dataset表示形式
        /// </summary>
        /// <param name="path">XML文档路径</param>
        /// <returns></returns>
        public static DataSet GetDataSet(string path)
        {
            DataSet ds = new DataSet();
            try
            {
                ds.ReadXml(path);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return ds;
        }
        /// <summary>
        /// 获取指定条件的节点
        /// </summary>
        /// <param name="path">路径</param>
        /// <param name="filter">条件</param>
        /// <param name="order">排序方式(可选)</param>
        /// <returns></returns>
        public static DataTable GetDataTable(string path, string filter, string order)
        {
            DataSet ds = GetDataSet(path);
            try
            {
                DataView view = new DataView(ds.Tables[0]);
                view.RowFilter = filter;
                if (!string.IsNullOrEmpty(order)) view.Sort = order;

                return view.ToTable();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// <summary>
        /// 为XML文档追加项/row
        /// </summary>
        /// <param name="path">路径</param>
        /// <param name="values">每一列值的组合</param>
        /// <returns></returns>
        public static DataSet AppendItem(string path, string[] values)
        {
            DataSet ds = GetDataSet(path);
            try
            {
                DataTable dt = ds.Tables[0];
                DataRow row = dt.NewRow();
                int cols = Math.Min(dt.Columns.Count, values.Length);
                for (int i = 0; i < cols; i++)
                {
                    row[i] = values[i];
                }
                dt.Rows.Add(row);
                dt.AcceptChanges();
                ds.AcceptChanges();
                ds.WriteXml(path);

                return ds;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// <summary>
        /// 在根节点下添加一个节点
        /// </summary>
        /// <param name="path"></param>
        /// <param name="parentNode"></param>
        public static void AddParentNode(string path, string parentNode)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(path);

            XmlElement Node = doc.CreateElement(parentNode);
            doc.DocumentElement.AppendChild(Node);

            doc.Save(path);
        }
        /// <summary>
        /// 插入一个节点
        /// </summary>
        /// <param name="path">XML文档路径</param>
        /// <param name="currNode">当前节点xpath</param>
        /// <param name="newElement">新节点名称</param>
        /// <param name="content">新节点内容</param>
        public static void InsertElement(string path, string currNode, string newElement, string content)
        {
            InsertElement(path, currNode, newElement, null, null, content);
        }
        /// <summary>
        /// 插入一个节点(带属性)
        /// </summary>
        /// <param name="path">文档路径</param>
        /// <param name="currNode">当前节点xpath</param>
        /// <param name="newElement">新节点名</param>
        /// <param name="attName">属性名</param>
        /// <param name="attValue">属性值</param>
        /// <param name="content">新节点内容</param>
        public static void InsertElement(string path, string currNode, string newElement, string attName, string attValue, string content)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(path);

            XmlNode node = doc.SelectSingleNode(currNode);
            XmlElement element = doc.CreateElement(newElement);

            if(!string.IsNullOrEmpty(attName))element.SetAttribute(attName, attValue);
            element.InnerText = content;

            node.AppendChild(element);

            doc.Save(path);
        }
        /// <summary>
        /// 向一个节点添加属性
        /// </summary>
        /// <param name="path">XML文档路径</param>
        /// <param name="currNode">当前节点xpath</param>
        /// <param name="attName">属性名称</param>
        /// <param name="attValue">属性值</param>
        public static void AddAttribute(string path, string currNode, string attName, string attValue)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(path);

            XmlAttribute att = doc.CreateAttribute(attName);
            att.Value = attValue;

            XmlNode node = doc.SelectSingleNode(currNode);
            node.Attributes.Append(att);

            doc.Save(path);
        }
        /// <summary>
        /// 删除一个节点
        /// </summary>
        /// <param name="path">XML文档路径</param>
        /// <param name="node">要删除的节点xpath</param>
        public static void RemoveNode(string path, string node)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(path);

            //string mainNode = node.Substring(0, node.LastIndexOf("/"));
            //doc.SelectSingleNode(mainNode).RemoveChild(doc.SelectSingleNode(node));
            XmlNode n = doc.SelectSingleNode(node); 
            n.ParentNode.RemoveChild(n);

            doc.Save(path);
        }
        /// <summary>
        /// 删除一个节点属性
        /// </summary>
        /// <param name="path">XML文档路径</param>
        /// <param name="currNode">属性所在节点xpath</param>
        /// <param name="attName">属性名</param>
        public static void RemoveAttribute(string path, string currNode, string attName)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(path);

            XmlElement xe = (XmlElement)doc.SelectSingleNode(currNode);
            xe.RemoveAttribute(attName);

            doc.Save(path);

        }
    }
}
